class CertGen {
  constructor(type) {

    this.certType = new CertType(type);
    this.detailSetting = new DetailSetting(type);
    this.certTypeMap = this.certType.certTypeMap;

    this.certData = {};
    let genCertList = (area, data, certList, options) => {
      (certList || []).forEach(certItem => {

        let list = data[certItem.dataSource] || [];
        let certs = genCerts(certItem, list, data);
        let ids = [];
        (certs || []).forEach(cert => {
          cert["certType"] = certType;
          cert["award"] = certType["name"];
          cert["code"] = certType["code"];
          certDataInfo[data.area].push(cert);
          let cert_ids = cert["list"].map(item => item["_id"]);
          ids.push(...cert_ids);
        });
        allCertIdsMap[certType["code"]] = ids;
      });
    };
    this.genAllCert = function (data, options = {}) {
      let certData = {};
      for (let area in this.certTypeMap) {
        let certList = this.certTypeMap[area];
        let areaData = data[area];
        certData[area] = genCertList(areaData, certList, options);
      }
      return certData;
    };

    /**
     * 生成评奖item
     * 生成pool数据
     * 过滤未报相应学科的团队或学生
     */
    let genPoolDataByGroup = (list, certItem) => {

      let scoreName = certItem["scoreName"];
      let scoreName2 = certItem["scoreName2"];

      let groupList = [{ "items": list, key: {} }];
      if (certItem["group"]) {
        groupList = list.groupBy(certItem["group"]);
      }
      (groupList || []).forEach(group => {
        group["gList"] = group["items"];
        let items = group["items"];
        let newItems = [];
        (items || []).forEach(item => {
          let newItem = { 
            data: item, id: item["_id"], 
            Name: item["Name"], Names: item["Names"]||"", 
            TestName: certItem.cnTestName,EnTestName: certItem.enTestName };
          if (item["ids"]) {
            newItem["ids"] = item["ids"];
          }
          if (certItem["pgType"] == "group") {
            newItem["items"] = item["items"];
          }
          if (!scoreName) {
            newItems.push(newItem);
            return;
          }
          // 未报此学科
          if (item["_null_" + scoreName] == 1) { return; }
          newItems.push(newItem);
          newItem.Score = item[scoreName];
          newItem.ScoreName = scoreName;
          if (scoreName2) { newItem.Score2 = item[scoreName2]; }

        });
        group["items"] = newItems;
      });
      return groupList;

    };

    /**
     * 过滤的在排除奖项中已获奖名单
     * @param poolList
     * @param dSetting
     * @param certIdsMap
     */
    let filterDataByExclude = (poolList, dSetting, certIdsMap) => {

      let list = [];
      let filterList = [];
      (poolList || []).forEach(item => {
        let isFind = false;
        (dSetting.excludeArray || []).forEach(code => {
          let ids = certIdsMap[code] || [];
          if (ids.includes(item["id"])) {
            item["_filter"] = code;
            filterList.push(item);
            isFind = true;
          }
        });
        if (!isFind) {
          list.push(item);
        }
      });
      return { list, filterList };

    };

    /**
     * 按分数分组,再排序
     * @param listNoSort
     * @param scoreName
     * @returns {*}
     */
    function groupSortScore(listNoSort, scoreName = "Score") {
      let listGroupByScore = listNoSort.groupBy([scoreName]);
      (listGroupByScore || []).forEach(g => g[scoreName] = g["key"][scoreName]);
      let list = listGroupByScore.sort((a, b) => {
        return toNumber(b[scoreName]) - toNumber(a[scoreName]);
      });
      return list;
    }

    /**
     * 每个pool里生成奖项名单
     * @param pool
     * @param certItem
     * @param dSetting
     * @param options
     */
    let genPoolCertList = (pool, certItem, dSetting, options) => {
      let items = pool.poolList || [];
      if (certItem.scoreName) {
        // 0分不评奖
        items = items.filter(item => toNumber(item.Score) > 0);
      }

      pool.list = items.sortBy("Score desc");
      //分组排序
      items = groupSortScore(items);
      let listNum = pool.listNum;
      let rank = 0;
      let maxRank = dSetting.certRateArray.length;
      let resultMap = {};
      pool.certs = [];
      pool.certList = [];
      pool.certSettings = [];

      let i = 0;
      for (let rank = 0; rank < maxRank; rank++) {
        let certRateItem = dSetting.certRateArray[rank];
        let certNum = certRateItem.getCertNum(listNum);
        pool.certSettings.push({ certRate: certRateItem.certRate, listNum, certNum });
        let resultArray = [];
        for (; i < items.length && rank < maxRank; i++) {

          // 当前名次,已评选有人的情况,如果下一批的人数将会超出设置人数,那么就放弃这一批人
          if (resultArray.length > 0 && (resultArray.length + items[i].items.length) > certNum) {
            break;
          }
          (items[i].items || []).forEach(item => {
            item["Rank"] = rank + 1;
            item["RankingCn"] = certRateItem.rankNameCn;
            item["Ranking"] = certRateItem.rankNameEn;
            // 根据荣誉清单中名次（英文）显示 20250430
            // item["RankingFull"]= item["RankingCn"] + "("+item["Ranking"]+")";
            item["RankingFull"] = item["Ranking"];
            item["Award"] = certItem["enName"];
            item["Area"] = options.poolKey["area"] == "all" ? "全国" : options.poolKey["area"];
            item["Track"] = certItem["mode"];

            item["certItem"] = certItem;
            options.genCertDetail && options.genCertDetail(certItem, item, rank, certRateItem, pool);
            resultArray.push(item);
          });

          //
          // if (resultArray.length >= certNum) {
          //   break;
          // }
        }
        pool.certs.push(resultArray);
        pool.certList.push(...resultArray);
        // 针对奖项,前是数值,后是百分比,如1,1,1,1,1,1,1,1,1,10%,10%的计算需要减掉前面人数
        if (certRateItem.rateType == "num") {
          listNum -= resultArray.length;
        }
      }

    };
    /**
     * 生成奖项
     * @param list
     * @param options{poolKey,genCertDetail}
     * @param certItem
     * @param certIdsMap 已获奖的ID
     * @returns {*[]}
     */
    this.genCert = function (myData, options, certItem, certIdsMap) {
      let resultList = [];
      let key = certItem.dataSource.format(options.poolKey || {});
      let list = myData[key] || [];
      if (list.length <= 0) {
        return resultList;
      }

      let pools = genPoolDataByGroup(list, certItem);
      (pools || []).forEach(pool => {
        let poolList = pool.items;
        let dSetting = this.detailSetting.getDetailItem(options.poolKey, pool.key);
        if (!dSetting) {
          pool.error = "未能正确找到奖项名次设置";
          return;
        }
        // 过滤的在排除奖项中已获奖名单
        let filterResult = filterDataByExclude(poolList, dSetting, certIdsMap);
        pool.filterList = filterResult.filterList;
        pool.poolList = filterResult.list;
        pool.certItem = certItem;
        pool.listNum = pool.poolList.length;

        if (certItem.filter){
          pool.poolList = certItem.filter(pool.poolList);
        }
  
        genPoolCertList(pool, certItem, dSetting, options);
      });
      return pools;
    };


  }
}